module.exports=[
    {name:'懒加载/按需加载',
    note:'“懒加载也叫延迟加载，即在需要的时候进行加载，随用随载。在单页应用中，如果没有应用懒加载，运用webpack打包后的文件将会异常的大，造成进入首页时，需要加载的内容过多，延时过长，不利于用户体验，而运用懒加载则可以将页面进行划分，需要的时候加载页面，可以有效的分担首页所承担的加载压力，减少首页加载用时。”',
    code:`
    链接:<a href='https://www.cnblogs.com/zhanyishu/p/6587571.html'>VUE组件懒加载浅析</a>
    <div class='c_idea'>
    <dl>
        <dt>路由懒加载</dt>
        <dd>
        <pre><code>
            //普通写法
            {
                path: '/home',
                name: 'home',
                component: require('@/views/Home.vue')
            }
            //懒加载写法
            {
                path: '/home',
                name: 'home',
                component: function(resolve){
                   require(['@/views/Home.vue'], resolve)
                }
            }
            //升级写法
            component:resolve => require(['@/views/Home.vue'], resolve)
            按需加载会在页面第一次请求的时候，把相关路由组件块的js添加上；
            非按需加载则会把所有的路由组件块的js包打在一起。当业务包很大的时候建议用路由的按需加载（懒加载）。
        </code></pre>
        </dd>
    </dl>
    <dl>
        <dt>vue组件按需加载</dt>
        <dd>
        <pre><code>
        //1、require.ensure()实现按需加载
        不进行页面按需加载引入方式：import  {button,from}   from '../../common/home.vue'
        进行页面按需加载的引入方式：const  home = r => require.ensure( [], () => r (require('../../common/home.vue')))
        require.ensure(dependencies:String [],callback:function(require),errorCallback:function(error),chunkName:String)
        // 第一个参数的依赖关系是一个数组，代表了当前需要进来的模块的一些依赖; 
        // 第二个参数回调就是一个回调函数其中需要注意的是，这个回调函数有一个参数要求，通过这个要求就可以在回调函数内动态引入其他模块值得注意的是，
                          虽然这个要求是回调函数的参数，理论上可以换其他名称，但是实际上是不能换的，否则的的的的WebPack就无法静态分析的时候处理它; 
        // 第三个参数errorCallback比较好理解，就是处理错误的回调; 
        // 第四个参数chunkName则是指定打包的组块名称。
        //2.vue异步组件技术
            在router中配置，使用这种方法可以实现按需加载，一个组件生成一个js文件
        {
            path: '/home',
            name: 'home',
            component:resove => require(['@/components/home'],resolve)
        }
        //3、使用动态的import()语法（推荐使用这种）
            没有指定webpackChunkName,每个组件打包成一个js文件
        const test1 = ()=>import('@/components/test1.vue') 
        const test2 = ()=>import('@/components/test2.vue')

        //指定了相同的webpackChunkName，会合并打包成y一个js文件
        const test3 = ()=>import(/* webpackChunkName:'grounpTest' */ '@/components/test3.vue') 
        const test4 = ()=>import(/* webpackChunkName:'grounpTest' */ '@/components/test4.vue')

        const router = new VueRouter({
            routes: [
                { path: '/test1', component: test1 },
                { path: '/test2', component: test2 },
                { path: '/test3', component: test3 },
                { path: '/test4', component: test4 }
            ]
        })

        </code></pre>
        </dd>
    </dl>
    `
    },
    {name:'自定义指令',
    note:'摘要',
    code:`
    <div class='c_idea'>
    <dl>
        <dt>自定义指令</dt>
        <dd>
        <pre><code>
        //1.创建指令
            //a.全局指令
            Vue.directive('focus',{
                // bind声明周期, 只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
                bind(el, binding, vnode, oldVnode){
                console.log('bind回调');
                },
                // 被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)
                inserted:function (el) {
                    el.focus()
                },
                // 所在组件的 VNode 更新时调用，但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
                update(el, binding, vnode, oldVnode){
                console.log('update回调', binding);
                },
                //指令所在组件的 VNode 及其子 VNode 全部更新后调用
                componentUpdated(el, binding, vnode, oldVnode){
                console.log('componentUpdated回调', binding);
                },
                unbind(el, binding, vnode, oldVnode){
                console.log('unbindd回调', binding);
                }
            }) 
            //b.局部指令
            directives:{  //和钩子函数一样使用
                focus:{
                inserted:function (el) {
                    el.focus()
                    }
                }
            } 
         //2.使用
         &lt;input type="text" v-model="dd" v-focus&gt;
        // 1、bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
        // 2、inserted：被绑定元素插入父节点时调用 (仅保证父节点存在，但不一定已被插入文档中)。
        // 3、update：所在组件的 VNode 更新时调用，但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变，也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 
        // 4、componentUpdated：指令所在组件的 VNode 及其子 VNode 全部更新后调用。
        // 5、unbind：只调用一次，指令与元素解绑时调用。
        // 指令钩子函数会被传入以下参数：
        // 1、el：指令所绑定的元素，可以用来直接操作 DOM 。
        // 2、binding：一个对象，包含以下属性：
        //             2-1、name：指令名，不包括 v- 前缀。
        //             2-2、value：指令的绑定值，例如：v-my-directive="1 + 1" 中，绑定值为 2。
        //             2-3、oldValue：指令绑定的前一个值，仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
        //             2-4、expression：字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中，表达式为 "1 + 1"。
        //             2-5、arg：传给指令的参数，可选。例如 v-my-directive:foo 中，参数为 "foo"。
        //             2-6、modifiers：一个包含修饰符的对象。例如：v-my-directive.foo.bar 中，修饰符对象为 { foo: true, bar: true }。
        // 3、vnode：Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
        // 4、oldVnode：上一个虚拟节点，仅在 update 和 componentUpdated 钩子中可用。
        // bind 钩子里绑定一些事件，在unbind 里用解绑事件，inserted操作dom
         
        </code></pre>
    </dl>
    </div>`
    },
    {name:'mixin混入',
    note:'Vue.mixin() 可以把你创建的自定义方法混入所有的 Vue 实例',
    code:`
    <div class='c_idea'>
    <dl>
        <dt>mixin</dt>
        <dd>
        <pre><code>
        //config.js 保存状态码对应的含义
        export const typeConfig = {
            1: "type one",
            2: "type two",
            3: "type three"
        }
        //filters.js  用于保存所有的自定义函数
        import { typeConfig } from "./config"
        export default {
            filters: {
                $_filterType: (value) => {
                return typeConfig[value] || "type undefined"
                }
            }
        }
        //main.js 中引入我们的 filters 方法集
        import filter from "./filters"
        Vue.mixin(filter)
        //使用
        <template>
            <div>{{typeStatus | $_filterType}}<div>
        </template>
        </code></pre>
    </dl></div>`
    },
    {name:'项目中的webpack',
    note:'摘要',
    code:`
    <div class='c_idea'>
    <dl>
        <dt>路由懒加载</dt>
        <dd>
        <pre><code>
        </code></pre>
    </dl></div>`
    },
    {name:'项目中的数据缓存',
    note:'摘要',
    code:`
    <div class='c_idea'>
    <dl>
        <dt>路由懒加载</dt>
        <dd>
        <pre><code>
        </code></pre>
    </dl></div>`
    },
    {name:'双向数据绑定',
    note:'摘要',
    code:`
    <div class='c_idea'>
    <dl>
        <dt>路由懒加载</dt>
        <dd>
        <pre><code>
        </code></pre>
    </dl></div>`
    },
    {name:'v-router',
    note:'摘要',
    code:`
    <a href='https://zhuanlan.zhihu.com/p/37730038'>路由详解</a>
    <div class='c_idea'>
    <dl>
        <dt>1. hash 模式</dt>
        <dd>
        <p>这种 #。后面 hash 值的变化，并不会导致浏览器向服务器发出请求，浏览器不发出请求，也就不会刷新页面。另外每次 hash 值的变化，还会触发hashchange 这个事件，通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作：</p>
        <pre><code>
        function matchAndUpdate () {
            // todo 匹配 hash 做 dom 更新操作
         }
         window.addEventListener('hashchange', matchAndUpdate)
        </code></pre>
    </dl>
    <dl>
        <dt>2. history 模式</dt>
        <dd>
        <p>14年后，因为 HTML5 标准发布。多了两个 API，pushState 和 replaceState，通过这两个 API 可以改变 url 地址且不会发送请求。同时还有popstate 事件。通过这些就能用另一种方式来实现前端路由了，但原理都是跟 hash 实现相同的。用了 HTML5 的实现，单页路由的 url 就不会多出一个#，变得更加美观。但因为没有 # 号，所以当用户刷新页面之类的操作时，浏览器还是会给服务器发送请求。为了避免出现这种情况，所以这个实现需要服务器的支持，需要把所有路由都重定向到根页面。</p>
        <pre><code>
        function matchAndUpdate () {
            // todo 匹配路径 做 dom 更新操作
         }
         window.addEventListener('popstate', matchAndUpdate)
        </code></pre>
    </dl>
    </div>`
    },
    {name:'vue常见面试',
    code:`
    <div class="c_idea">
    <dl>
        <dt>1. vue-router 使用params与query传参有什么区别</dt>
        <dd>
        <pre><code>
        // 传递
        this.$router.push({path: './xxx', params: {xx:xxx}})
        this.$router.push({path: './xxx', query: {xx:xxx}})
        // 接收
        this.$route.params
        this.$route.query
        params 是路由的一部分,必须要有。query 是拼接在 url 后面的参数，没有也没关系
        params 不设置的时候，刷新页面或者返回参数会丢，query 则不会有这个问题
        </code></pre>
        </dd>
    </dl>
    <dl>
        <dt>2. vue优缺点</dt>
        <dd> 良好的交互体验  良好的前后端工作分离模式</dd>
        <dd> SEO难度较高  兼容性</dd>
    </dl>
    <dl>
        <dt>3. vue核心是什么</dt>
        <dd> 数据驱动 组件系统</dd>
    </dl>
    <dl>
        <dt>4. vue中key作用</dt>
        <dd>key 的特殊属性主要用在 Vue 的虚拟 DOM 算法，在新旧 nodes 对比时辨识 VNodes。如果不使用 key，Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key，它会基于 key 的变化重新排列元素顺序，并且会移除 key 不存在的元素。</dd>
        <dd>有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误</dd>
    </dl>
    <dl>
        <dt>5. mvvm和mvc区别 <a href='http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html'>阮一峰讲解</a></dt>
        <dd>
            <h5>mvc </h5>
           <p>View 传送指令到 Controller 完成业务逻辑后，要求 Model 改变状态 Model 将新的数据发送到 View，用户得到反馈</p>
           <p>直接通过controller接受指令 完成业务逻辑后，要求 Model 改变状态 Model 将新的数据发送到 View，用户得到反馈</p>
        </dd>
        <dd>mvvm  就是view操作vm  vm影响model ;;或者v改变影响vm vm改变m</dd>
    </dl>
    <dl>
        <dt>6. $route和$router的区别</dt>
        <dd>$router 为 VueRouter 实例，想要导航到不同 URL，则使用 $router.push 方法</dd>
        <dd>$route 为当前 router 跳转对象里面可以获取 name 、 path 、 query 、 params 等</dd>
    </dl>
    <dl>
        <dt>7. NextTick 是做什么的</dt>
        <dd>$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调，在修改数据之后使用 $nextTick，则可以在回调中获取更新后的 DOM</dd>
        <dd><a href='https://cn.vuejs.org/v2/guide/reactivity.html'>深入响应式原理</a></dd>
    </dl>
    <dl>
        <dt>8. Vue 组件 data 为什么必须是函数</dt>
        <dd>因为js本身的特性带来的，如果 data 是一个对象，那么由于对象本身属于引用类型，当我们修改其中的一个属性时，会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象，那么每一个实例的 data 属性都是独立的，不会相互影响了</dd>
    </dl>
    <a href='https://github.com/muwoo/blogs.git'>xx的博客</a>
    </div>

    `
    }
]
